<?php

namespace app\api\model\house;

use app\admin\model\Crontab;
use app\api\model\coupon\Coupon;
use app\api\model\Holidays;
use app\api\model\house\House as HouseModel;
use app\api\model\user\UserOccupant;
use think\Db;
use think\Model;
use app\common\model\User as UserModel;


class OrderCreate extends Model
{

    protected $error = 0;  //是否有错误
    protected $error_msg = '';  //错误描述

    // 订单创建
    const ORDER_CREATE = 0;

    // 订单待入住
    const ORDER_WAIT_CHECKIN = 1;

    //已入住
    const ORDER_CHECKIN = 2;

    //已退房
    const ORDER_CHECKIN_OUT = 4;

    //已完成
    const ORDER_COMPLETE = 10;

    //已取消
    const ORDER_CLOSE = -1;

    public $order_status = [
        self::ORDER_CREATE           => [
            'status'          => self::ORDER_CREATE,
            'name'            => '待支付',
        ],
        self::ORDER_WAIT_CHECKIN           => [
            'status'          => self::ORDER_WAIT_CHECKIN,
            'name'            => '待入住',
        ],
        self::ORDER_CHECKIN           => [
            'status'          => self::ORDER_CHECKIN,
            'name'            => '已入住',
        ],
        self::ORDER_CHECKIN_OUT           => [
            'status'          => self::ORDER_CHECKIN_OUT,
            'name'            => '已退房',
        ],
        self::ORDER_COMPLETE           => [
            'status'          => self::ORDER_COMPLETE,
            'name'            => '已完成',
        ],
        self::ORDER_CLOSE           => [
            'status'          => self::ORDER_CLOSE,
            'name'            => '已取消',
        ],
    ];

    public $change_type_list = [0=>'非业主积分换房',1=>'业主免费换房'];

    //换房提交订单页展示
    public function changecalculate($data)
    {
        $house_id = $data['house_id'];
        $user_id = $data['user_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];
        $occupant_id = $data['occupant_id'];
        $complement_id = $data['complement_id'];
        //throw new \Exception('异常');
        $user = UserModel::where(['id'=>$user_id])->field('id,nickname,score,level,level_type')->find();

        $user_level = $user->level;
        $user_level_type = $user->level_type;

        if (empty($checkin_date)){
            throw new \Exception('请传入入住日期');
        }
        if (empty($leave_date)){
            throw new \Exception('请传入离店日期');
        }

        $house_info = House::where(['house_id'=>$house_id])
            ->field('house_id,user_id,mode,house_attr,house_title,address,is_group,house_level,bed_num')
            ->find();

        if (!$house_info){
            throw new \Exception('该房源不存在');
        }

        if (!in_array(3,explode(',',$house_info['mode']))){
            throw new \Exception('该房源不支持换房');
        }

        //$date_list = [];
        $complement_money = 0;//服务金额
        $house_money = 0;//房屋金额
        //$management_money = 0;//换房的管理费
        //$hydropower_money = 0;//免费换房的水电费
        //$use_score = 0;//换房使用的积分
        //$earn_score = 0;//换房挣的积分,例如高业主等级换低等级房屋

        $house_level = $house_info['house_level'];//房屋等级
        $bed_num = $house_info['bed_num'];//卧室数量

        if ($user_level_type==2||$user_level_type==3){
            //业主换房
            if ($house_level-$user_level>1){
                throw new \Exception('只可对应业主会员等级跨一级换房');
            }
            $score_res = $this->calculateChangeScore($user_level,$house_level,1);
            $change_type = 1;
        } else {
            //会员换房
            $res = $this->canChange($user_level,$house_level);
            if ($res['code']==0){
                throw new \Exception($res['message']);
            }
            $score_res = $this->calculateChangeScore($user_level,$house_level,0);
            $change_type = 0;
        }

        $use_score = $score_res['reduce_score'];
        $earn_score = $score_res['add_score'];

        if ($use_score>0&&$use_score>$user->score){
            throw new \Exception('积分不足');
        }

        //配套服务
        $complement = HouseComplementPrice::where(['house_id'=>$house_id])
            ->field('id,house_id,name,unit,price')
            ->select();

        $user_occupant_list = [];
        //入住人
        if (!empty($occupant_id)){
            $user_occupant_list = UserOccupant::where('id','in',$occupant_id)
                ->where(['user_id'=>$user_id])
                ->field('id,name,id_card_num,mobile')->select();
        }

        $days = getDaysBetweenTwoTimestamps($checkin_date,$leave_date);

        //服务金额
        if (count($complement_id)>0){
            $complement_money = $this->getComplementPrice($complement_id);
        }
        $order_money = bcadd($house_money,$complement_money);

        //管理费
        $management_money = $this->managementPriceCalculate($house_level,$days);
        $order_money = bcadd($order_money,$management_money);

        //水电费
        $hydropower_money = $this->hydropowerPriceCalculate($bed_num,$days);
        $order_money = bcadd($order_money,$hydropower_money);

        $pay_money = $order_money;

        //生成入住所有日期
        $start = new \DateTime($checkin_date);
        $end = new \DateTime($leave_date);

        $dates = array();

        while ($start <= $end) {
            $dates[] = $start->format('Y-m-d');
            $start->modify('+1 day');
        }

        array_pop($dates);

        $date_list = [];

        foreach ($dates as $date) {
            $date_list[] = [
                'date'=>$date,
            ];
        }

        //积分换算公式
        $score_formula = "(积分换算公式:下单人/房东={$use_score}/+{$earn_score})";

        return  [
            'house_info'=>$house_info,
            'complement'=>$complement,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
            'user_occupant_list'=>$user_occupant_list,
            'order_money'=>$order_money,
            'house_money'=>$house_money,
            'complement_money'=>$complement_money,
            'pay_money'=>$pay_money,
            'use_score'=>$use_score,
            'earn_score'=>$earn_score,
            'management_money'=>$management_money,
            'hydropower_money'=>$hydropower_money,
            'days'=>$days,
            'date_list'=>$date_list,
            'user_info'=>$user,
            'score_formula'=>$score_formula,
            'change_type'=>$change_type,
            'change_type_name'=>$this->change_type_list[$change_type]
        ];
    }

    //换房订单提交
    public function changeordercreate($data)
    {
        $complement_id = $data['complement_id'];//服务
        $house_id = $data['house_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];
        $calculate_data = $this->changecalculate($data);

        $model = new HouseModel();
        $house_data = [
            'house_id'=>$house_id,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
        ];
        $info = $model->canCheckin($house_data);

        if ($info==0){
            throw new \Exception('与可预定时间冲突');
        }

        if (isset($calculate_data[ 'code' ]) && $calculate_data[ 'code' ] < 0)
            return $calculate_data;

        if ($this->error > 0) {
            throw new \Exception($this->error_msg);
        }

        if ($calculate_data['use_score']>0&&$calculate_data['use_score']>$calculate_data['user']['score']){
            throw new \Exception('积分不足');
        }


        Db::startTrans();

        try {
            $order_model = new HouseOrder();

            $order_data = [
                'user_id'=>$data['user_id'],
                'owner_id'=>$calculate_data['house_info']['user_id'],
                'house_id'=>$calculate_data['house_info']['house_id'],
                'house_title'=>$calculate_data['house_info']['house_title'],
                'order_type'=>3,
                'order_type_name'=>'换房',
                'order_status'=>self::ORDER_CREATE,
                'order_status_name'=> $this->order_status[self::ORDER_CREATE]["name"],
                'order_no'=>$this->order_no(),
                'change_type'=>$calculate_data['change_type'],
                'change_type_name'=>$calculate_data['change_type_name'],
                'house_money'=>$calculate_data['house_money'],
                'complement_money'=>$calculate_data['complement_money'],
                'order_money'=>$calculate_data['order_money'],
                'pay_money'=>$calculate_data['pay_money'],
                'use_score'=>$calculate_data['use_score'],
                'earn_score'=>$calculate_data['earn_score'],
                'management_money'=>$calculate_data['management_money'],
                'hydropower_money'=>$calculate_data['hydropower_money'],
                'checkin_date'=>$calculate_data['checkin_date'],
                'leave_date'=>$calculate_data['leave_date'],
                'days'=>$calculate_data['days'],
            ];

            $res = $order_model->save($order_data);
            if ($res){
                $order_id = $order_model->order_id;

                //扣积分
                if ($order_model->use_score<0){
                    UserModel::score($order_model->use_score,$order_model->user_id,$calculate_data['change_type_name'].'换房扣除',$order_model->order_id);
                }

                //添加选择的入住人
                $order_occupant_model = new HouseOrderOccupant();
                $order_occupant_data = [];
                foreach ($calculate_data['user_occupant_list'] as $k=>$v){
                    $order_occupant_data[] = [
                        'order_id'=>$order_id,
                        'user_id'=>$data['user_id'],
                        'name'=>$v['name'],
                        'id_card_num'=>$v['id_card_num'],
                        'mobile'=>$v['mobile'],
                    ];
                }

                $order_occupant_model->saveAll($order_occupant_data);

                //添加选择的服务
                $order_complement_model = new HouseOrderComplement();
                $order_complement_data = [];
                $user_complement_list = $this->getOrderComplementList($complement_id);

                foreach ($user_complement_list as $k=>$v){
                    $order_complement_data[] = [
                        'order_id'=>$order_id,
                        'num'=>$v['num'],
                        'house_complement_price_id'=>$v['id'],
                        'single_money'=>$v['single_money'],
                        'total_money'=>$v['total_money'],
                        'name'=>$v['name'],
                        'unit'=>$v['unit'],
                    ];
                }
                $order_complement_model->saveAll($order_complement_data);

                //添加每日的价格
                $order_date_model = new HouseOrderDate();
                $order_date_data = [];
                foreach ($calculate_data['date_list'] as $k=>$v){
                    $order_date_data[] = [
                        'order_id'=>$order_id,
                        'date'=>$v['date'],
                    ];
                }
                $order_date_model->saveAll($order_date_data);

                //定时任务关闭订单
                $cron = new Crontab();
                $close_time = \app\common\model\Config::get(['name'=>'house_close_time'])->value;
                $end_time_timestamp = time()+60*$close_time;
                $cron_data = [
                    'type'=>'url',
                    'title'=>'关闭房屋订单,订单id:'.$order_id,
                    'content'=>request()->domain().'/api/houseorder/cancel?order_id='.$order_id,
                    'schedule'=>schedule($end_time_timestamp),
                    'maximums'=>1,
                    'begintime'=>time(),
                    'endtime'=>$end_time_timestamp,
                    'status'=>'normal'
                ];
                $cron->save($cron_data);
                Db::commit();
                return $order_model->order_no;
            } else {
                Db::rollback();
                throw new \Exception('提交失败');
            }

        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
        }

    }

    //管理费计算
    public function managementPriceCalculate($house_level,$day)
    {
        $price_arr = [1=>2,2=>3,3=>5,4=>8,5=>12];

        $price = $price_arr[$house_level];

        $total_price = bcmul($price,$day,2);

        return $total_price;
    }

    //水电费计算
    public function hydropowerPriceCalculate($bed_num,$day)
    {
        $price_arr = [1=>8,2=>12,3=>15];

        if ($bed_num<=3){
            $price = $price_arr[$bed_num];
        } else {
            $price = ($bed_num-3)*5+15;
        }

        $total_price = bcmul($price,$day,2);

        return $total_price;
    }

    //拼房提交订单页展示
    public function groupcalculate($data)
    {
        $house_id = $data['house_id'];
        $user_id = $data['user_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];
        $coupon_id = $data['coupon_id'];
        $complement_id = $data['complement_id'];
        $bed_occupant_id = $data['bed_occupant_id'];

        if (empty($checkin_date)){
            throw new \Exception('请传入入住日期');
        }
        if (empty($leave_date)){
            throw new \Exception('请传入离店日期');
        }

        $house_info = House::where(['house_id'=>$house_id])
            ->field('house_id,user_id,mode,house_attr,house_title,address,group_stay_discount,group_weekday_price,
            group_weekend_price,group_highday_price,bed_index,is_group,house_level')
            ->find();

        if (!$house_info){
            throw new \Exception('该房源不存在');
        }
        $group_stay_discount = $house_info['group_stay_discount']?json_decode($house_info['group_stay_discount'],true):[];
        $group_weekday_price = json_decode($house_info['group_weekday_price'],true);
        $group_weekend_price = json_decode($house_info['group_weekend_price'],true);
        $group_highday_price = json_decode($house_info['group_highday_price'],true);

        //配套服务
        $complement = HouseComplementPrice::where(['house_id'=>$house_id])
            ->field('id,house_id,name,unit,price')
            ->select();

        //$order_money = 0;//订单总金额
        //$pay_money = 0;//付款金额
        $discount_money = 0;//折扣金额
        $coupon_money = 0;//优惠券金额
        $complement_money = 0;//服务金额
        $house_money = 0;//房屋金额

        $days = getDaysBetweenTwoTimestamps($checkin_date,$leave_date);

        //卧室列表
        $mode = explode(',',$house_info['mode']);
        $bed_index = explode(',',$house_info['bed_index']);
        $house_bed_list = HouseBedInfo::where(['house_id'=>$house_id])
            ->field('bed_id,house_id,index,bed_name,bed_type,live_people_num,limit_people_num')
            ->select();
        $house_model = new House();
        foreach ($house_bed_list as $k=>$v){
            if (in_array(4,$mode)){
                if (in_array($v['index'],$bed_index)){
                    $status_name = '自住';
                    $status = '2';
                } else {
                    $conflict = $house_model->bedstatus($house_id,$v['bed_id'],$checkin_date,$leave_date);
                    if ($conflict){
                        $status_name = '已拼';
                        $status = '3';
                    } else {
                        $status_name = '待拼';
                        $status = '1';
                    }
                }
            } else {
                $conflict = $house_model->bedstatus($house_id,$v['bed_id'],$checkin_date,$leave_date);
                if ($conflict){
                    $status_name = '已拼';
                    $status = '3';
                } else {
                    $status_name = '待拼';
                    $status = '1';
                }
            }
            $house_bed_list[$k]['status_name'] = $status_name;
            $house_bed_list[$k]['status'] = $status;
            foreach ($group_weekday_price as $kk=>$vv){
                if ($v['index']==$vv['type']){
                    $house_bed_list[$k]['weekday_price'] = $vv['price'];
                }
            }
            foreach ($group_weekend_price as $kk=>$vv){
                if ($v['index']==$vv['type']){
                    $house_bed_list[$k]['weekend_price'] = $vv['price'];
                }
            }
            foreach ($group_highday_price as $kk=>$vv){
                if ($v['index']==$vv['type']){
                    $house_bed_list[$k]['highday_price'] = $vv['price'];
                }
            }
        }

        //入驻卧室的日期/价格/入住人
        $group_bed_info_list = [];
        $group_bed_occupant = [];
        //房屋总金额
        if (count($bed_occupant_id)>0){
            $house_res = $this->getHouseGroupPrice($checkin_date,$leave_date,$house_bed_list,$bed_occupant_id);

            $house_money = $house_res['house_money'];
            $group_bed_info_list =  $house_res['date_list'];
            $group_bed_occupant =  $house_res['user_occupant_list'];
        }

        //优惠券列表
        $coupon_list = $this->getOrderCouponList($user_id,$house_money);

        //服务金额
        if (count($complement_id)>0){
            $complement_money = $this->getComplementPrice($complement_id);
        }

        $order_money = bcadd($house_money,$complement_money);
        $pay_money = $order_money;

        //连住天数超过3天享折扣
        if ($days>3&&count($group_stay_discount)>0){
            $discount_res = $this->getDiscountPrice($group_stay_discount,$days,$house_money,$group_bed_info_list);

            $discount_money = $discount_res['discount_money'];
            $pay_money = bcsub($pay_money,$discount_money,2);
            $group_bed_info_list = $discount_res['date_list'];
        }

        //计算优惠券
        if ($coupon_id){
            $coupon_money = $this->couponPromotion($coupon_id,$user_id,$house_money);
            $pay_money = bcsub($pay_money,$coupon_money,2);
        }

        return [
            'house_info'=>$house_info,
            'complement'=>$complement,
            'coupon_list'=>$coupon_list,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
            'order_money'=>$order_money,
            'house_money'=>$house_money,
            'complement_money'=>$complement_money,
            'pay_money'=>$pay_money,
            'discount_money'=>$discount_money,
            'coupon_money'=>$coupon_money,
            'days'=>$days,
            'coupon_id'=>$coupon_id,
            'house_bed_list'=>$house_bed_list,
            'group_bed_info_list'=>$group_bed_info_list,
            'group_bed_occupant'=>$group_bed_occupant
        ];
    }

    //拼房提交订单
    public function groupordercreate($data)
    {
        $complement_id = $data['complement_id'];//服务
        $bed_occupant_id = $data['bed_occupant_id'];
        $house_id = $data['house_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];

        $model = new HouseModel();
        $house_data = [
            'house_id'=>$house_id,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
        ];
        $info = $model->pinfangStatus($house_data);
        if ($info==0){
            throw new \Exception('已拼满');
        }

        $calculate_data = $this->groupcalculate($data);

        if (isset($calculate_data[ 'code' ]) && $calculate_data[ 'code' ] < 0)
            return $calculate_data;
        if ($this->error > 0) {
            throw new \Exception($this->error_msg);
        }

        Db::startTrans();

        try {

            $order_model = new HouseOrder();

            $order_data = [
                'user_id'=>$data['user_id'],
                'owner_id'=>$calculate_data['house_info']['user_id'],
                'house_id'=>$calculate_data['house_info']['house_id'],
                'house_title'=>$calculate_data['house_info']['house_title'],
                'order_type'=>2,
                'order_type_name'=>'拼房',
                'order_status'=>self::ORDER_CREATE,
                'order_status_name'=> $this->order_status[self::ORDER_CREATE]["name"],
                'order_no'=>$this->order_no(),
                'house_money'=>$calculate_data['house_money'],
                'complement_money'=>$calculate_data['complement_money'],
                'order_money'=>$calculate_data['order_money'],
                'coupon_id'=>$calculate_data['coupon_id'],
                'coupon_money'=>$calculate_data['coupon_money'],
                'pay_money'=>$calculate_data['pay_money'],
                'discount_money'=>$calculate_data['discount_money'],
                'checkin_date'=>$calculate_data['checkin_date'],
                'leave_date'=>$calculate_data['leave_date'],
                'days'=>$calculate_data['days'],
                'bed_id'=>implode(',',array_column($bed_occupant_id,'bed_id'))
            ];

            $res = $order_model->save($order_data);
            if ($res){
                $order_id = $order_model->order_id;

                //添加选择的入住人
                $order_occupant_model = new HouseOrderOccupant();
                $order_occupant_data = [];
                foreach ($calculate_data['group_bed_occupant'] as $k=>$v){

                    foreach ($v['occupant_list'] as $kk=>$vv){
                        $order_occupant_data[] = [
                            'order_id'=>$order_id,
                            'user_id'=>$data['user_id'],
                            'bed_id'=>$v['bed_id'],
                            'name'=>$vv['name'],
                            'id_card_num'=>$vv['id_card_num'],
                            'mobile'=>$vv['mobile'],
                        ];
                    }
                }

                $order_occupant_model->saveAll($order_occupant_data);
                //添加选择的服务
                $order_complement_model = new HouseOrderComplement();
                $order_complement_data = [];
                $user_complement_list = $this->getOrderComplementList($complement_id);

                foreach ($user_complement_list as $k=>$v){
                    $order_complement_data[] = [
                        'order_id'=>$order_id,
                        'num'=>$v['num'],
                        'house_complement_price_id'=>$v['id'],
                        'single_money'=>$v['single_money'],
                        'total_money'=>$v['total_money'],
                        'name'=>$v['name'],
                        'unit'=>$v['unit'],
                    ];
                }
                $order_complement_model->saveAll($order_complement_data);

                //修改优惠券状态
                if ($order_model->coupon_id){
                    $coupon_model = new Coupon();
                    $coupon_result = $coupon_model->useCoupon($order_model->coupon_id,$order_model->user_id,$order_id);
                    if (!$coupon_result) {
                        Db::rollback();
                        throw new \Exception('优惠券使用失败');
                    }
                }

                //添加每日的价格
                $order_date_model = new HouseOrderDate();
                $order_date_data = [];
                foreach ($calculate_data['group_bed_info_list'] as $k=>$v){
                    $order_date_data[] = [
                        'order_id'=>$order_id,
                        'bed_id'=>$v['bed_id'],
                        'date'=>$v['date'],
                        'price'=>$v['price'],
                        'discount_price'=>bcsub($v['price'],$v['discount_price'],2),
                    ];
                }

                $order_date_model->saveAll($order_date_data);

                //定时任务关闭订单
                $cron = new Crontab();
                $close_time = \app\common\model\Config::get(['name'=>'house_close_time'])->value;
                $end_time_timestamp = time()+60*$close_time;
                $cron_data = [
                    'type'=>'url',
                    'title'=>'关闭房屋订单,订单id:'.$order_id,
                    'content'=>request()->domain().'/api/houseorder/cancel?order_id='.$order_id,
                    'schedule'=>schedule($end_time_timestamp),
                    'maximums'=>1,
                    'begintime'=>time(),
                    'endtime'=>$end_time_timestamp,
                    'status'=>'normal'
                ];
                $cron->save($cron_data);
                Db::commit();
                return $order_model->order_no;
            } else {
                Db::rollback();
                throw new \Exception('提交失败');
            }


        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage().'-'.$e->getLine());
        }

    }


    //提交订单页展示
    public function calculate($data)
    {
        $house_id = $data['house_id'];
        $user_id = $data['user_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];
        $occupant_id = $data['occupant_id'];
        $coupon_id = $data['coupon_id'];
        $complement_id = $data['complement_id'];

        if (empty($checkin_date)){
            throw new \Exception('请传入入住日期');
        }
        if (empty($leave_date)){
            throw new \Exception('请传入离店日期');
        }

        $house_info = House::where(['house_id'=>$house_id])
            ->field('house_id,user_id,mode,house_attr,house_title,address,stay_discount,share_weekday_price,share_weekend_price,
            share_highday_price,is_group,house_level')
            ->find();

        if (!$house_info){
            throw new \Exception('该房源不存在');
        }

        $date_list = [];
        $discount_money = 0;//折扣金额
        $coupon_money = 0;//优惠券金额
        $complement_money = 0;//服务金额

        $house_info['stay_discount'] = json_decode($house_info['stay_discount'],true);
        $weekday_price = $house_info['share_weekday_price'];
        $weekend_price = $house_info['share_weekend_price'];
        $highday_price = $house_info['share_highday_price'];

        //配套服务
        $complement = HouseComplementPrice::where(['house_id'=>$house_id])
            ->field('id,house_id,name,unit,price')
            ->select();

        $user_occupant_list = [];
        //入住人
        if (!empty($occupant_id)){
            $user_occupant_list = UserOccupant::where('id','in',$occupant_id)
                ->where(['user_id'=>$user_id])
                ->field('id,name,id_card_num,mobile')->select();
        }

        $days = getDaysBetweenTwoTimestamps($checkin_date,$leave_date);

        //房屋总金额
        $house_res = $this->getHousePrice($checkin_date,$leave_date,$weekday_price,$weekend_price,$highday_price);
        $house_money = $house_res['house_money'];

        //优惠券列表
        $coupon_list = $this->getOrderCouponList($user_id,$house_money);

        //服务金额
        if (count($complement_id)>0){
            $complement_money = $this->getComplementPrice($complement_id);
        }

        $order_money = bcadd($house_money,$complement_money);
        $pay_money = $order_money;

        //连住天数超过3天享折扣
        if ($days>3&&count($house_info['stay_discount'])>0){
            $discount_res = $this->getDiscountPrice($house_info['stay_discount'],$days,$house_money,$house_res['date_list']);
            $discount_money = $discount_res['discount_money'];
            $pay_money = bcsub($pay_money,$discount_money,2);
            $date_list = $discount_res['date_list'];
        }

        //计算优惠券
        if ($coupon_id){
            $coupon_money = $this->couponPromotion($coupon_id,$user_id,$house_money);
            $pay_money = bcsub($pay_money,$coupon_money,2);
        }

        return [
            'house_info'=>$house_info,
            'complement'=>$complement,
            'coupon_list'=>$coupon_list,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
            'user_occupant_list'=>$user_occupant_list,
            'order_money'=>$order_money,
            'house_money'=>$house_money,
            'complement_money'=>$complement_money,
            'pay_money'=>$pay_money,
            'discount_money'=>$discount_money,
            'coupon_money'=>$coupon_money,
            'days'=>$days,
            'coupon_id'=>$coupon_id,
            'date_list'=>$date_list
        ];
    }


    //提交订单
    public function ordercreate($data)
    {
        $complement_id = $data['complement_id'];//服务
        $house_id = $data['house_id'];
        $checkin_date = $data['checkin_date'];
        $leave_date = $data['leave_date'];
        $calculate_data = $this->calculate($data);

        $model = new HouseModel();
        $house_data = [
            'house_id'=>$house_id,
            'checkin_date'=>$checkin_date,
            'leave_date'=>$leave_date,
        ];
        $info = $model->canCheckin($house_data);

        if ($info==0){
            throw new \Exception('与可预定时间冲突');
        }

        if (isset($calculate_data[ 'code' ]) && $calculate_data[ 'code' ] < 0)
            return $calculate_data;
        if ($this->error > 0) {
            throw new \Exception($this->error_msg);
        }

        Db::startTrans();

        try {
            $order_model = new HouseOrder();

            $order_data = [
                'user_id'=>$data['user_id'],
                'owner_id'=>$calculate_data['house_info']['user_id'],
                'house_id'=>$calculate_data['house_info']['house_id'],
                'house_title'=>$calculate_data['house_info']['house_title'],
                'order_type'=>1,
                'order_type_name'=>'整屋',
                'order_status'=>self::ORDER_CREATE,
                'order_status_name'=> $this->order_status[self::ORDER_CREATE]["name"],
                'order_no'=>$this->order_no(),
                'house_money'=>$calculate_data['house_money'],
                'complement_money'=>$calculate_data['complement_money'],
                'order_money'=>$calculate_data['order_money'],
                'coupon_id'=>$calculate_data['coupon_id'],
                'coupon_money'=>$calculate_data['coupon_money'],
                'pay_money'=>$calculate_data['pay_money'],
                'discount_money'=>$calculate_data['discount_money'],
                'checkin_date'=>$calculate_data['checkin_date'],
                'leave_date'=>$calculate_data['leave_date'],
                'days'=>$calculate_data['days'],
            ];

            $res = $order_model->save($order_data);
            if ($res){
                $order_id = $order_model->order_id;

                //添加选择的入住人
                $order_occupant_model = new HouseOrderOccupant();
                $order_occupant_data = [];
                foreach ($calculate_data['user_occupant_list'] as $k=>$v){
                    $order_occupant_data[] = [
                        'order_id'=>$order_id,
                        'user_id'=>$data['user_id'],
                        'name'=>$v['name'],
                        'id_card_num'=>$v['id_card_num'],
                        'mobile'=>$v['mobile'],
                    ];
                }

                $order_occupant_model->saveAll($order_occupant_data);
                //添加选择的服务
                $order_complement_model = new HouseOrderComplement();
                $order_complement_data = [];
                $user_complement_list = $this->getOrderComplementList($complement_id);

                foreach ($user_complement_list as $k=>$v){
                    $order_complement_data[] = [
                        'order_id'=>$order_id,
                        'num'=>$v['num'],
                        'house_complement_price_id'=>$v['id'],
                        'single_money'=>$v['single_money'],
                        'total_money'=>$v['total_money'],
                        'name'=>$v['name'],
                        'unit'=>$v['unit'],
                    ];
                }
                $order_complement_model->saveAll($order_complement_data);

                //修改优惠券状态
                if ($order_model->coupon_id){
                    $coupon_model = new Coupon();
                    $coupon_result = $coupon_model->useCoupon($order_model->coupon_id,$order_model->user_id,$order_id);
                    if (!$coupon_result) {
                        Db::rollback();
                        throw new \Exception('优惠券使用失败');
                    }
                }

                //添加每日的价格
                $order_date_model = new HouseOrderDate();
                $order_date_data = [];
                foreach ($calculate_data['date_list'] as $k=>$v){
                    $order_date_data[] = [
                        'order_id'=>$order_id,
                        'date'=>$v['date'],
                        'price'=>$v['price'],
                        'discount_price'=>bcsub($v['price'],$v['discount_price'],2),
                    ];
                }
                $order_date_model->saveAll($order_date_data);
                //定时任务关闭订单
                $cron = new Crontab();
                $close_time = \app\common\model\Config::get(['name'=>'house_close_time'])->value;
                $end_time_timestamp = time()+60*$close_time;
                $cron_data = [
                    'type'=>'url',
                    'title'=>'关闭房屋订单,订单id:'.$order_id,
                    'content'=>request()->domain().'/api/houseorder/cancel?order_id='.$order_id,
                    'schedule'=>schedule($end_time_timestamp),
                    'maximums'=>1,
                    'begintime'=>time(),
                    'endtime'=>$end_time_timestamp,
                    'status'=>'normal'
                ];
                $cron->save($cron_data);
                Db::commit();
                return $order_model->order_no;
            } else {
                Db::rollback();
                throw new \Exception('提交失败');
            }

        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage());
        }

    }

    //拼房房屋价格计算
    public function getHouseGroupPrice($start_date,$end_date,$house_bed_list,$bed_occupant_id)
    {

        // 生成所有日期
        $start = new \DateTime($start_date);
        $end = new \DateTime($end_date);

        $dates = array();

        while ($start <= $end) {
            $dates[] = $start->format('Y-m-d');
            $start->modify('+1 day');
        }
        $holidays = Holidays::where(['type'=>0])->column('date');
        $workdays = Holidays::where(['type'=>1])->column('date');

        // 计算总租金
        $total_rent = 0;
        array_pop($dates);

        $list = [];
        $user_occupant_list = [];
        //$bed_arr = explode(',',$bed_id);
        foreach ($house_bed_list as $k=>$v){
            $holiday_rent = $v['highday_price'];
            $weekend_rent = $v['weekend_price'];
            $weekday_rent = $v['weekday_price'];
            foreach ($bed_occupant_id as $kk=>$vv){
                if ($v['bed_id']==$vv['bed_id']){
                    if ($v['status']!=1){
                        throw new \Exception($v['bed_name'].'卧室不可拼');
                    }
                    //$user_occupant_list = [];
                    if ($vv['occupant_id']){
                        $occupant_list = UserOccupant::where('id','in',$vv['occupant_id'])
                            ->field('id,name,id_card_num,mobile')->select();
                        $user_occupant_list[] = [
                            'bed_id'=>$v['bed_id'],
                            'occupant_list'=>$occupant_list
                        ];
                    }

                    foreach ($dates as $date) {
                        $current_date = new \DateTime($date);

                        if (in_array($date, $holidays)) {
                            $list[] = [
                                'bed_id'=>$v['bed_id'],
                                'date'=>$date,
                                'price'=>$holiday_rent,
                                'discount_price'=>0
                            ];
                            $total_rent += $holiday_rent;
                            continue;
                        }

                        // 判断是否是周末
                        $day_of_week = $current_date->format('N');
                        if ($day_of_week == 6 || $day_of_week == 7) {
                            if (!in_array($date, $workdays)){
                                $list[] = [
                                    'bed_id'=>$v['bed_id'],
                                    'date'=>$date,
                                    'price'=>$weekend_rent,
                                    'discount_price'=>0
                                ];
                                $total_rent += $weekend_rent;
                            } else {
                                $list[] = [
                                    'bed_id'=>$v['bed_id'],
                                    'date'=>$date,
                                    'price'=>$weekday_rent,
                                    'discount_price'=>0
                                ];
                                $total_rent += $weekday_rent;
                            }

                            continue;
                        }

                        $list[] = [
                            'bed_id'=>$v['bed_id'],
                            'date'=>$date,
                            'price'=>$weekday_rent,
                            'discount_price'=>0
                        ];
                        // 工作日
                        $total_rent += $weekday_rent;
                    }

                }
            }

        }

        return [
            'house_money'=>$total_rent,
            'date_list'=>$list,
            'user_occupant_list'=>$user_occupant_list
        ];
    }

    //订房房屋价格计算
    public function getHousePrice($start_date,$end_date,$weekday_rent,$weekend_rent,$holiday_rent)
    {
        // 生成所有日期
        $start = new \DateTime($start_date);
        $end = new \DateTime($end_date);

        $dates = array();

        while ($start <= $end) {
            $dates[] = $start->format('Y-m-d');
            $start->modify('+1 day');
        }
        $holidays = Holidays::where(['type'=>0])->column('date');
        $workdays = Holidays::where(['type'=>1])->column('date');
        // 计算总租金
        $total_rent = 0;
        array_pop($dates);

        $list = [];

        foreach ($dates as $date) {
            $current_date = new \DateTime($date);

            if (in_array($date, $holidays)) {
                $list[] = [
                    'date'=>$date,
                    'price'=>$holiday_rent
                ];
                $total_rent += $holiday_rent;
                continue;
            }

            // 判断是否是周末
            $day_of_week = $current_date->format('N');
            if ($day_of_week == 6 || $day_of_week == 7) {
                if (!in_array($date, $workdays)){
                    $list[] = [
                        'date'=>$date,
                        'price'=>$weekend_rent
                    ];
                    $total_rent += $weekend_rent;
                } else {
                    $list[] = [
                        'date'=>$date,
                        'price'=>$weekday_rent
                    ];
                    $total_rent += $weekday_rent;
                }

                continue;
            }

            $list[] = [
                'date'=>$date,
                'price'=>$weekday_rent
            ];
            // 工作日
            $total_rent += $weekday_rent;
        }

        return [
            'house_money'=>$total_rent,
            'date_list'=>$list
        ];
    }

    //计算服务价格
    public function getComplementPrice($complement_id)
    {
        $complement_price = 0;
        $complement_list = $complement_id;
        //$complement_list  = json_decode($complement_id,true)?json_decode($complement_id,true):_json_decode($complement_id);
        foreach ($complement_list as $k=>$v){
            $info = HouseComplementPrice::get($v['id']);
            $price =  bcmul($v['num'],$info['price'],2);
            $complement_price+=$price;

        }

        return $complement_price;
    }

    //反服务列表
    public function getOrderComplementList($complement_id)
    {
        $new_complement_list = [];
        $complement_list = $complement_id;

        //$complement_list  = json_decode($complement_id,true)?json_decode($complement_id,true):_json_decode($complement_id);
        foreach ($complement_list as $k=>$v){
            $info = HouseComplementPrice::get($v['id']);

            $price =  bcmul($v['num'],$info['price'],2);
            //$complement_price+=$price;
            $arr = [
                'num'=>$v['num'],
                'id'=>$v['id'],
                'single_money'=>$info['price'],
                'total_money'=>$price,
                'name'=>$info['name'],
                'unit'=>$info['unit'],
            ];
            array_push($new_complement_list,$arr);
        }

        return $new_complement_list;
    }

    //计算连住折扣金额
    public function getDiscountPrice($stay_discount,$day,$house_money,$date_list=[])
    {
        $discount_money = 0;
        $discount = 10;
        $stay_discount_list = $stay_discount;

        //$stay_discount_list = json_decode($stay_discount,true);
        foreach ($stay_discount_list as $k=>$v){
            if ($day<$v['max_day']&&$day>$v['min_day']){
                $discount = $v['discount'];
                continue;
            }
        }

        $use_discount = 1-$discount/100;

        foreach ($date_list as $k=>$v){
            $discount_price = bcmul($v['price'],$use_discount,2);
            $date_list[$k]['discount_price'] = $discount_price;
            $discount_money = bcadd($discount_money,$discount_price,2);

        }

        return [
            'discount_money'=>$discount_money,
            'date_list'=>$date_list
        ];
    }

    //优惠券活动
    public function couponPromotion($coupon_id,$user_id,$house_money)
    {
        $coupon_money = 0;
        $coupon_house_money = 0;
        $is_coupon = false;

        $coupon_info = Coupon::get($coupon_id);

        if ($coupon_info[ 'user_id' ] == $user_id && $coupon_info[ 'state' ] == 1){
            if ($coupon_info[ 'at_least' ] <= $house_money) {
                $is_coupon = true;
            } else {
                $this->error = 1;
                $this->error_msg = "优惠券不可用!";
                /*return [
                    'code'=>0,
                    'msg'=>'优惠券不可用!'
                ];*/
            }
            $coupon_house_money = $house_money;
        }

        if ($is_coupon){
            $coupon_money = $coupon_info[ 'money' ] > $coupon_house_money ? $coupon_house_money : $coupon_info[ 'money' ];
        } else {
            $this->error = 1;
            $this->error_msg = "优惠券不可用!";
        }

        return $coupon_money;
    }

    //优惠券列表
    public function getOrderCouponList($user_id,$house_money)
    {
        $list = Coupon::where(['user_id'=>$user_id,'state'=>1])
            ->where('at_least','<=',$house_money)
            ->where('end_time','>',time())
            ->select();
        return $list;
    }

    public function order_no(){
        $order_no = null;
        while (true) {
            $order_no = date('YmdHis') . mt_rand(1000, 9999);
            $exist_order_no = HouseOrder::get(['order_no' => $order_no]);
            if (!$exist_order_no) {
                break;
            }
        }
        return $order_no;
    }


    //判断非业主会员是否符合换房
    public function canChange($user_level,$house_level)
    {
        //非业主会员
        if ($user_level==1){
            if (in_array($house_level,[2,3,4])){
                error('普享会员不能预定乐选房屋/优选房屋/尊选房屋');
            }
        } elseif ($user_level==2){
            if (in_array($house_level,[3,4])){
                error('普享会员不能预定优选房屋/尊选房屋');
            }
        } elseif ($user_level==3){
            if ($house_level==4){
                error('普享会员不能预定尊选房屋');
            }
        }
        success();
    }

    //计算换房用户扣的积分和业主加的积分
    public function calculateChangeScore($user_level,$house_level,$is_owner=0)
    {
        if ($is_owner==1){
            //业主
            $score_arr = [
                1=>[
                    1=>['add_score'=>1,'reduce_score'=>0],
                    2=>['add_score'=>1,'reduce_score'=>-1],
                    3=>['add_score'=>2,'reduce_score'=>-2],
                    4=>['add_score'=>3,'reduce_score'=>-3],
                    5=>['add_score'=>4,'reduce_score'=>-4],
                ],
                2=>[
                    1=>['add_score'=>1,'reduce_score'=>0],
                    2=>['add_score'=>1,'reduce_score'=>-1],
                    3=>['add_score'=>2,'reduce_score'=>-2],
                    4=>['add_score'=>3,'reduce_score'=>-3],
                    5=>['add_score'=>4,'reduce_score'=>-4],
                ],
                3=>[
                    1=>['add_score'=>1,'reduce_score'=>0],
                    2=>['add_score'=>1,'reduce_score'=>-1],
                    3=>['add_score'=>2,'reduce_score'=>-2],
                    4=>['add_score'=>3,'reduce_score'=>-3],
                    5=>['add_score'=>4,'reduce_score'=>-4],
                ],
                4=>[
                    1=>['add_score'=>1,'reduce_score'=>0],
                    2=>['add_score'=>1,'reduce_score'=>-1],
                    3=>['add_score'=>2,'reduce_score'=>-2],
                    4=>['add_score'=>3,'reduce_score'=>-3],
                    5=>['add_score'=>4,'reduce_score'=>-4],
                ],
                5=>[
                    1=>['add_score'=>1,'reduce_score'=>0],
                    2=>['add_score'=>1,'reduce_score'=>-1],
                    3=>['add_score'=>2,'reduce_score'=>-2],
                    4=>['add_score'=>3,'reduce_score'=>-3],
                    5=>['add_score'=>4,'reduce_score'=>-4],
                ],
            ];
            $reduce_score = $score_arr[$user_level][$house_level]['reduce_score'];
            $add_score = $score_arr[$user_level][$house_level]['add_score'];
        } else {
            //非业主会员
            $score_arr = [
                1=>[1=>1, 2=>2],
                2=>[1=>1, 2=>2, 3=>3,],
                3=>[1=>1, 2=>2, 3=>3, 4=>4],
                4=>[1=>1, 2=>2, 3=>3, 4=>4, 5=>5,],
                5=>[1=>1, 2=>2, 3=>3, 4=>4, 5=>5,],
            ];
            $reduce_score = $score_arr[$user_level][$house_level];
            $add_score = $score_arr[$user_level][$house_level];
        }

        $data =  [
            'reduce_score'=>$reduce_score,
            'add_score'=>$add_score
        ];

        return $data;
    }
}